﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharpSoft.Geometries
{
    public class GeometryHelper
    {
        /// <summary>
        /// 获取多边形的正外接矩形
        /// </summary>
        /// <param name="points"></param>
        /// <returns></returns>
        public static Rect GetPositiveOuterRectangle(Point2D[] points)
        {
            if (points == null)
            {
                throw new ArgumentNullException(nameof(points));
            }
            var minx = 0d;
            var maxx = 0d;
            var miny = 0d;
            var maxy = 0d;
            foreach (var p in points)
            {
                minx = Math.Min(minx, p.X);
                miny = Math.Min(miny, p.Y);
                maxx = Math.Max(maxx, p.X);
                maxy = Math.Max(maxy, p.Y);
            }

            return new Rect(minx, miny, maxx - minx, maxy - miny);
        }

        /// <summary>
        /// 获取直角三角形的临边长
        /// </summary>
        /// <param name="hypotenuse">斜边长</param>
        /// <param name="radian">夹角</param>
        /// <returns></returns>
        public static double GetAdjacentSide(double hypotenuse, Radian radian)
        {
            var l = hypotenuse * Math.Cos((double)radian);
            return l;
        }
        /// <summary>
        /// 获取直角三角形的对边长
        /// </summary>
        /// <param name="hypotenuse">斜边长度</param>
        /// <param name="radian">夹角</param>
        /// <returns></returns>
        public static double GetOppositeSide(double hypotenuse, Radian radian)
        {
            var l = hypotenuse * Math.Sin((double)radian);
            return l;
        }
        /// <summary>
        /// 获取点指定方位指定距离的点坐标
        /// </summary>
        /// <param name="p"></param>
        /// <param name="length"></param>
        /// <param name="angle"></param>
        /// <returns></returns>
        public static Point2D GetAzimuthPoint(Point2D p, double length, Radian angle)
        {
            var lb = GeometryHelper.GetAdjacentSide(length, angle);//
            var db = GeometryHelper.GetOppositeSide(length, angle);

            var tan = Math.Tan((double)angle);
            if (tan >= 0)
            {
                tan = 1;
            }
            else if (tan < 0)
            {
                tan = -1;
            }
            var px = db;// * tan;
            var py = lb;// * tan;
            return new Point2D(px + p.X, py + p.Y);
        }
        /// <summary>
        /// （回转数法）判断点是否在多边形内部
        /// </summary>
        /// <param name="p"></param>
        /// <param name="poly"></param>
        /// <returns></returns>
        /// <remarks>
        /// 当回转数为 0 时，点在闭合曲线外部。https://blog.csdn.net/Form_/article/details/77855163
        /// </remarks>
        public static bool IsPointInPolygon(Point2D p, Point2D[] poly)
        {
            Polygon polygon = new Polygon(poly);
            return polygon.Contains(p);
        }

    }
}
